# 导包
import tornado.web

# 服务器
from tornado import httpserver

# 导入基础类
from base import BaseHandler,WsBaseHandler

# 导入数据库操作类
from db import database,User,myser,MyMongo,Role

# 异步执行库
import peewee_async
import hashlib

import json

from tools import ret_json,send_mail,MyJwt,Chat

from playhouse.shortcuts import model_to_dict


import random
import datetime
import re

import pytz
# 设置时区
tzinfo = pytz.timezone('Asia/Shanghai')

import requests


# 绘图库

from PIL import ImageDraw
from PIL import Image

# io库
import io

# 时间模块
import time


import base64
import hmac
from hashlib import sha256

import urllib

import os

import jwt


from functools import wraps

# 导入队列类
from test_queue import MyQueueSort,RedisQueue,ChatQueue

import redis

# 消息类
class Msg:

	# 记录当前的链接用户
	connector = {}

	# 用户加入链接
	def user_connect(self,user):

		if user not in self.connector:

			self.connector[user] = "user"

	# 断开链接
	def user_del(self,user):

		self.connector.pop(user)

	# 发消息
	def send(self,message):

		for user in self.connector:

			user.write_message(message)



# 客服相关接口
class ClientHandler(BaseHandler):


	# 同步客服状态
	async def post(self):

		id = self.get_argument("id",None)

		state = self.get_argument("state",None)


		r = redis.Redis(decode_responses=True)

		r.set("client%s" % id,state)


		return self.write(ret_json({"code":200,"msg":"同步状态成功"})) 



	# 查询客服
	async def get(self):

		id = self.get_argument("id",None)

		user = await self.application.objects.get(User.select().where(User.id==id))


		self.write(ret_json({"clientid":user.clientid}))


	# 设置客服
	async def put(self):

		# 当前用户id
		id = self.get_argument("id",None)

		# 客服id
		clientid = self.get_argument("clientid",None)

		user = await self.application.objects.get(User.select().where(User.id==id))

		# 设置客服id
		user.clientid = clientid

		# 异步修改
		await self.application.objects.update(user)

		return self.write(ret_json({"code":200,"msg":"设置成功"}))






# websocket 主动推送视图
class WsHandler(WsBaseHandler):


	def open(self):

		#self.write_message("你好，这里是后端")

		Msg().user_connect(self)

	def on_close(self):

		Msg().user_del(self)

	# 接收消息方法
	def on_message(self,message):

		self.write_message(message)


# 客户出队接口

class OutServer(BaseHandler):

	async def get(self):

		chatqueue = ChatQueue("chat")

		# 出队
		uid = chatqueue.pop(type="server")

		return self.write(ret_json({"uid":uid}))



# 主动推送消息接口
class Push(BaseHandler):

	async def get(self):

		msg = self.get_argument("msg",None)

		key = self.get_argument("key",None)


		# 存储消息
		chat = Chat()
		chat.push(key,msg)

		# 发送消息
		Msg().send(msg)

		return self.write(ret_json({"msg":"发送消息成功"}))


# 聊天记录信息接口
class ChatList(Push):

	async def get(self):

		key = self.get_argument("key",None)

		id = self.get_argument("id",None)

		if id is not None:

			# 入队
			chatqueue = ChatQueue("chat")

			chatqueue.push(id)

		print(key)

		# 获取聊天记录
		chat = Chat()
		chatlist = chat.get(key)

		print(chatlist)

		return self.write(ret_json(chatlist))






# 定义装饰器
def before_request(func):

	@wraps(func)
	def wrapper(self,*args,**kwargs):

		id = self.get_argument("id",None)
		token = self.get_argument("token",None)
		if token is None:

			return self.write(ret_json({"code":403,"msg":"您未登录"}))

		token = jwt.decode(token,"123",algorithms=["HS256"])

		if token['id'] != int(id):

			return self.write(ret_json({"code":403,"msg":"您的密钥非法"}))

		return func(self,*args,**kwargs)

	return wrapper



# 运营接口
class Ocview(BaseHandler):

	async def get(self):

		id = self.get_argument("id",None)

		# 出队
		#mq = MyQueueSort()
		#mq.pop(int(id))

		# 查询审核中的用户
		users = await self.application.objects.execute(User.select().where((User.state==3) & (User.id != id) & (User.auid == id) ))

		users = [myser(x) for x in users]


		return self.write(ret_json(users))

# 表单结果入库
class AuditUpdate(BaseHandler):

	# 返回用户审核状态
	@before_request
	async def get(self):

		id = self.get_argument("id",None)

		user = await self.application.objects.get(User.select().where(User.id==id))
		# 序列化
		user = myser(user)
		return self.write(ret_json(user))


	async def put(self):

		id = self.get_argument("id",None)

		audit = self.get_argument("audit",None)

		user = await self.application.objects.get(User.select().where(User.id==id))

		# 赋值
		user.audit = audit
		user.state = 3

		await self.application.objects.update(user)

		# 入队
		#mq = MyQueueSort()
		#mq.push(int(id))
		rq = RedisQueue("rq123")

		mylist = rq.find(id)
		if str(id) not in mylist:
			rq.put(int(id))

		return self.write(ret_json({"code":200,"msg":"提交审核资料成功"}))


# 文件上传
class Upload(BaseHandler):

	async def post(self):

		file = self.request.files['file']

		type = self.get_argument("type",None)


		for meta in file:

			filename = meta['filename']

			with open("./static/"+filename,"wb") as f:

				f.write(meta["body"])

		if type == "audit":

			return self.write(ret_json({"code":200,"msg":"上传审批文件成功","filename":filename}))

		else:

			return self.write(ret_json({"code":200,"msg":"上传广告素材成功","filename":filename}))


# 用户角色配置
class UserRole(BaseHandler):

	async def get(self):

		type = self.get_argument("type",None)

		# 查询

		role = await self.application.objects.get(Role.select().where(Role.id == type))

		return self.write(ret_json(role.audit))




# 用户接口
class UserInfo(BaseHandler):

	async def get(self):

		username = self.get_argument("username",None)
		password = self.get_argument("password",None)
		type = self.get_argument("type",None)

		# 查询
		try:
			user = await self.application.objects.get(User.select().where( (User.username == username) & (User.password == password) & (User.type == type) ))

			# 生成token
			token = jwt.encode({'id':user.id},"123",algorithm='HS256')

			print(token)

			return self.write(ret_json({"code":200,"msg":"登录成功","id":user.id,"type":user.type,"username":user.username,"token":token}))

		except Exception as e:

			print(str(e))

			return self.write(ret_json({"code":403,"msg":"您的用户名或者密码有误"}))

	async def post(self):

		username = self.get_argument("username",None)
		password = self.get_argument("password",None)

		type = self.get_argument("type",None)

		# 入库操作
		try:

			user = await self.application.objects.create(User,username=username,password=password,type=type)

			return self.write(ret_json({"code":200,"msg":"注册成功"}))

		except Exception as e:

			return self.write(ret_json({"code":403,"msg":"您的账号已经被注册"}))
